package com.sea.base.widget

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.customview.widget.ViewDragHelper
import java.lang.Integer.max
import java.lang.Integer.min
import kotlin.math.abs

/**
 * 左滑删除的控件
 * 1.必须有2个child，第一个主view，第二个滑出的view
 * 2.不支持margin
 * 3.高度以第一个view为准，所以第二个view可以使用match_parent
 */
class LeftSwipeLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : ViewGroup(context, attrs, defStyleAttr, defStyleRes) {
    private lateinit var firstView: View
    private lateinit var secondView: View

    private val dragHelper = ViewDragHelper.create(this, object : ViewDragHelper.Callback() {
        override fun tryCaptureView(child: View, pointerId: Int) = firstView === child
        override fun getViewHorizontalDragRange(child: View) = firstView.width
        override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int) = min(max(-secondView.width, left), 0)

        override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) {
            secondView.offsetLeftAndRight(dx)
            invalidate()
        }

        override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
            val maxVel = 750
            if (releasedChild === firstView) {
                isExpand = when {
                    xvel < -maxVel -> true
                    xvel > maxVel -> false
                    else -> firstView.left < -secondView.width / 2
                }
            }
        }
    }
    )

    var canDrag = true
        set(value) {
            if (field != value) {
                field = value
                if (!canDrag) {
                    isExpand = false
                }
            }
        }

    var isExpand = true
        set(value) {
            field = value
            val left = if (field) -secondView.width else 0
            if (dragHelper.smoothSlideViewTo(firstView, left, 0)) {
                postInvalidateOnAnimation()
            }
            onExpandChangedListener?.invoke(field)
        }

    var onExpandChangedListener: ((Boolean) -> Unit)? = null

    override fun onViewAdded(child: View) {
        super.onViewAdded(child)
        if (childCount > 2) {
            throw IllegalArgumentException("仅支持2个child")
        }
        if (childCount == 2) {
            firstView = getChildAt(0)
            secondView = getChildAt(1)
        }
    }

    override fun computeScroll() {
        if (dragHelper.continueSettling(true)) {
            postInvalidateOnAnimation()
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        measureChild(firstView, widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(firstView.measuredWidth, firstView.measuredHeight)
        measureChild(
            secondView,
            MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY)
        )
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        firstView.layout(0, 0, measuredWidth, measuredHeight)
        val sTop = (measuredHeight - secondView.measuredHeight) / 2
        secondView.layout(measuredWidth, sTop, secondView.measuredWidth + measuredWidth, sTop + secondView.measuredHeight)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent) = if (canDrag) dragHelper.shouldInterceptTouchEvent(ev) else super.onInterceptTouchEvent(ev)

    private var downX = 0f
    private var isBeingDragged = false
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (canDrag) {
            dragHelper.processTouchEvent(event)
            when (event.action) {
                MotionEvent.ACTION_DOWN -> downX = event.x
                MotionEvent.ACTION_MOVE -> {
                    if ((!isBeingDragged) && abs(event.x - downX) >= dragHelper.touchSlop) {
                        parent.requestDisallowInterceptTouchEvent(true)
                        isBeingDragged = true
                    }
                }

                else -> {
                    val oldState = isBeingDragged
                    isBeingDragged = false
                    if (oldState) {
                        //drag消费过就不要给super了，防止出现点击事件和滑动冲突
                        return true
                    }
                }
            }
        }
        //点击事件等功能
        return super.onTouchEvent(event)
    }
}